# OOP——面向对象编程

# 定义Document类
# 类:一群有着相同的属性和函数的对象的集合
class Document:
    # 常量
    # 常量一般用全大写表示

    WELCOME_STR = 'Welcome! The context of this book is {}.'

    # 构造函数
    # 构造函数:在创建对象时被自动调用的函数
    def __init__(self, title, author, context):
        print('init function in class Document is invoked...')
        self.title = title
        self.author = author
        self.__context = context  # 以__开头的属性为私有属性,无法在类的外部被访问和修改

    # 类函数
    # 类函数最常用的功能就是定义不同的init构造器
    @classmethod
    def create_empty_book(cls, title, author):
        return cls(title=title, author=author, context='nothing')

    # 成员函数
    # 第一个参数self表示当前对象的引用
    def get_context_length(self):
        return len(self.__context)

    # 成员函数
    def intercept_context(self, length):
        self.__context = self.__context[:length]

    # 静态函数
    @staticmethod
    def get_welcome(context):
        return Document.WELCOME_STR.format(context)


if __name__ == '__main__':
    # 创建Document类的对象
    harry_potter_book = Document(title='Harry Potter', author='J.K. Rowling',
                                 context='... Forever Do not believe any thing is capable of thinking independently ...')
    # 访问对象的属性与方法
    print(f'title = {harry_potter_book.title}')
    print(f'author = {harry_potter_book.author}')
    print(f'context length = {harry_potter_book.get_context_length()}')

    harry_potter_book.intercept_context(10)
    print(f'after intercept, context length = {harry_potter_book.get_context_length()}')

    # 直接访问对象的私有属性会报错
    # print(f'context = {harry_potter_book.__context}')

    # 使用类函数创建对象
    empty_book = Document.create_empty_book(title='The Little Prince', author='Antoine de Saint-Exupéry')
    print(f'empty book title = {empty_book.title}')
    print(f'empty book context length = {empty_book.get_context_length()}')

    # 调用类的静态函数
    print(f'welcome = {Document.get_welcome("indeed nothing")}')
